package com.crm.miaohe.service;

import static com.crm.miaohe.common.ApplicationConstant.REPORT_EXPORT_TYPE_PACKAGE;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.text.Collator;
import java.text.ParseException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

import com.crm.miaohe.controller.erp.response.Wuliao;
import com.kingdee.bos.webapi.sdk.QueryParam;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.logging.log4j.util.Strings;
import org.jxls.builder.xls.XlsCommentAreaBuilder;
import org.jxls.common.Context;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import com.crm.miaohe.app.service.WxService;
import com.crm.miaohe.common.ApplicationConstant;
import com.crm.miaohe.controller.PageResponse;
import com.crm.miaohe.controller.order.request.OrderCustomRequest;
import com.crm.miaohe.controller.order.request.OrderDeliveryDateRequest;
import com.crm.miaohe.controller.order.request.OrderDetailsModQtyRequest;
import com.crm.miaohe.controller.order.request.OrderDetailsRequest;
import com.crm.miaohe.controller.order.request.OrderExportRequest;
import com.crm.miaohe.controller.order.request.OrderExportStatusRequest;
import com.crm.miaohe.controller.order.request.OrderFreightFeeRequest;
import com.crm.miaohe.controller.order.request.OrderMemoRequest;
import com.crm.miaohe.controller.order.request.OrderPlanRequest;
import com.crm.miaohe.controller.order.request.OrderQueryRequest;
import com.crm.miaohe.controller.order.request.OrderStatusRequest;
import com.crm.miaohe.controller.order.request.OrderWuliuRequest;
import com.crm.miaohe.entity.dto.ConfigEntity;
import com.crm.miaohe.entity.order.OrderCustomerEntity;
import com.crm.miaohe.entity.order.OrderDetailEntity;
import com.crm.miaohe.entity.order.OrderDetailPriceStrategyEntity;
import com.crm.miaohe.entity.order.OrderDriverExportEntity;
import com.crm.miaohe.entity.order.OrderEntity;
import com.crm.miaohe.entity.order.OrderErpEntity;
import com.crm.miaohe.entity.order.OrderErpExportEntity;
import com.crm.miaohe.entity.order.OrderFreightFeeEntity;
import com.crm.miaohe.exception.ErpBusinessException;
import com.crm.miaohe.kdcloud.api.Order;
import com.crm.miaohe.kdcloud.api.query.BillNumber;
import com.crm.miaohe.kdcloud.api.query.ModelNumber;
import com.crm.miaohe.kdcloud.model.NumberRecord;
import com.crm.miaohe.kdcloud.model.OrderForm;
import com.crm.miaohe.mapper.TblCustomerMapper;
import com.crm.miaohe.mapper.TblDepositDetailsMapper;
import com.crm.miaohe.mapper.TblOrderApiMapper;
import com.crm.miaohe.mapper.TblOrderDetailsMapper;
import com.crm.miaohe.mapper.TblOrderMapper;
import com.crm.miaohe.mapper.TblPriceStrategyItemMapper;
import com.crm.miaohe.mapper.TblUserOpenidMapper;
import com.crm.miaohe.mapper.interceptor.MetadataInterceptor;
import com.crm.miaohe.model.TblCustomer;
import com.crm.miaohe.model.TblCustomerExample;
import com.crm.miaohe.model.TblDepositDetails;
import com.crm.miaohe.model.TblOrder;
import com.crm.miaohe.model.TblOrderDetails;
import com.crm.miaohe.model.TblOrderDetailsExample;
import com.crm.miaohe.model.TblOrderErpExample;
import com.crm.miaohe.model.TblOrderExample;
import com.crm.miaohe.model.TblUserOpenid;
import com.crm.miaohe.model.TblUserOpenidExample;
import com.crm.miaohe.utils.EachRightCommand;
import com.crm.miaohe.utils.IdGeneratorService;
import com.crm.miaohe.utils.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.nimbusds.jose.util.JSONObjectUtils;

import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    private final MetadataInterceptor metadataInterceptor;

    private final TblCustomerMapper customerMapper;
    private final TblPriceStrategyItemMapper priceStrategyItemMapper;
    private final TblOrderMapper orderMapper;
    private final TblOrderApiMapper orderApiMapper;
    private final TblOrderDetailsMapper orderDetailsMapper;
    private final K3CloudApiService k3CloudApiService;
    private final IdGeneratorService idGeneratorService;
    private final ObjectMapper objectMapper;
    private final ConfigService configService;
    private final TblDepositDetailsMapper depositDetailsMapper;
    private final TblUserOpenidMapper tblUserOpenidMapper;
   
    public LocalDateTime F_DLMH_DATE;//要货日期
    public final int pageSize = 24;
    private final Collator kanjiCollator = Collator.getInstance(java.util.Locale.CHINESE);

    @Autowired private WxService wxService;
   
    
    public OrderServiceImpl(TblCustomerMapper customerMapper,
                            TblPriceStrategyItemMapper priceStrategyItemMapper,
                            TblOrderMapper orderMapper,
                            TblOrderApiMapper orderApiMapper,
                            TblOrderDetailsMapper orderDetailsMapper,
                            K3CloudApiService k3CloudApiService,
                            IdGeneratorService idGeneratorService,
                            ConfigService configService,
                            ObjectMapper objectMapper,
                            TblDepositDetailsMapper depositDetailsMapper, 
                            TblUserOpenidMapper tblUserOpenidMapper, MetadataInterceptor metadataInterceptor) {
        this.customerMapper = customerMapper;
        this.priceStrategyItemMapper = priceStrategyItemMapper;
        this.orderMapper = orderMapper;
        this.orderApiMapper = orderApiMapper;
        this.orderDetailsMapper = orderDetailsMapper;
        this.k3CloudApiService = k3CloudApiService;
        this.idGeneratorService = idGeneratorService;
        this.depositDetailsMapper = depositDetailsMapper;
        this.configService = configService;
        this.objectMapper = objectMapper;
        this.tblUserOpenidMapper = tblUserOpenidMapper;
        this.metadataInterceptor = metadataInterceptor;
    }

//    @Override
//    public void createOrder(OrderPlanRequest request) {
//        String username = SecurityContextHolder.getContext().getAuthentication().getName();
//        // 查询当前用户信息（销售组织、客户编码、业务员）
//        TblCustomerExample example = new TblCustomerExample();
//        example.createCriteria().andPhoneNumberEqualTo(username).andDeletedEqualTo(false);
//        TblCustomer customer = customerMapper.selectByExample(example).stream().findAny()
//                .orElseThrow(() -> {
//                    log.error("当前客户不存在。用户名：[{}]", username);
//                    throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.CUS003, username);
//                });
//        log.info("客户[{}]将要创建[{}]个订单。", customer.getPhoneNumber(), request.getProductInfos().size());
//        OrderForm orderForm = new OrderForm();
//        orderForm.setDeleteEntry(true);
//        orderForm.setVerifyBaseDataField(false);
//        orderForm.setEntryBatchFill(true);
//        orderForm.setValidateFlag(true);
//        orderForm.setNumberSearch(true);
//        OrderForm.Model model = new OrderForm.Model();
//        model.setFBillTypeID(new NumberRecord(ApplicationConstant.STANDARD_ORDER_CODE)); // 标准销售订单Code
//        model.setFDate(new Date());
//        model.setFSaleOrgId(new NumberRecord(customer.getOrganizationCode()));
//        model.setFCustId(new NumberRecord(customer.getCustomerNum()));
//        model.setFReceiveId(new NumberRecord(customer.getCustomerNum()));
//        model.setFSalerId(new NumberRecord(customer.getBizCode()));
//        OrderForm.Model.SaleOrderFinance finance = new OrderForm.Model.SaleOrderFinance();
//        finance.setFSettleCurrId(new NumberRecord("PRE001"));
//        finance.setFIsPriceExcludeTax(true);
//        finance.setFIsIncludedTax(true);
//        model.setFSaleOrderFinance(finance);
//
//        //多个商品的情况
//        List<OrderForm.Model.SaleOrderEntry> list = new ArrayList<>();
//        for (OrderPlanRequest.ProductInfo productInfo : request.getProductInfos()) {
//            OrderForm.Model.SaleOrderEntry saleOrderEntry = new OrderForm.Model.SaleOrderEntry();
//
//            //saleOrderEntry.setFPrice(productInfo.get());
//            saleOrderEntry.setFTaxPrice(productInfo.getPrice()/productInfo.getFqty());
//
//            saleOrderEntry.setFMaterialId(new NumberRecord(productInfo.getProductCode()));
//            saleOrderEntry.setFUnitID(new NumberRecord(ApplicationConstant.DEFAULT_UNIT_ID));
//            saleOrderEntry.setFQty(Double.parseDouble(String.valueOf(productInfo.getFqty())));
//            saleOrderEntry.setFPriceUnitId(new NumberRecord(ApplicationConstant.DEFAULT_UNIT_ID));
//
//            saleOrderEntry.setFDeliveryDate(productInfo.getFDeliveryDate());
//
//            saleOrderEntry.setFSettleOrgIds(new NumberRecord(customer.getOrganizationCode()));
//            saleOrderEntry.setFReserveType(ApplicationConstant.DEFAULT_RESERVE_TYPE);
//            saleOrderEntry.setFStockUnitID(new NumberRecord(ApplicationConstant.DEFAULT_UNIT_ID));
//            list.add(saleOrderEntry);
//        }
//        model.setFSaleOrderEntry(list);
//        orderForm.setModel(model);
//        if (log.isDebugEnabled()) {
//            log.debug("===================================================");
//            log.debug("=============  即将提交订单到金蝶ERP系统  =============");
//            log.debug("===================================================");
//        }
//        k3CloudApiService.save("SAL_SaleOrder", orderForm);
//        if (log.isDebugEnabled()) {
//            log.debug("===================================================");
//            log.debug("==================  订单提交成功！  ==================");
//            log.debug("===================================================");
//        }
//    }

    @Override
    public String queryFRECCONDITIONID (String customerNum) {

        String filter = String.join("", "FNumber = '", customerNum + "'");
        List<ModelNumber> fNumber = k3CloudApiService
                .executeBillQuery("BD_Customer", "FRECCONDITIONID.fnumber", filter, ModelNumber.class);


        if (!ObjectUtils.isEmpty(fNumber)) {
            return fNumber.get(0).getFNUMBER();
        }

        return "";
    }





    @Override
    public List<Order> queryOrderDetail(String username) {
        TblCustomerExample example = new TblCustomerExample();
        example.createCriteria().andPhoneNumberEqualTo(username);
        TblCustomer currentUser = customerMapper.selectByExample(example)
                .stream().findFirst()
                .orElseThrow(() -> {
                    log.error("当前登录客户[{}]信息不存在，请检查数据库。", username);
                    throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.CUS003, username);
                });
        String filter = String.join("", "FCUSTID = ", currentUser.getCustomerId() + "");
        List<BillNumber> orderNumbers = k3CloudApiService
                .executeBillQuery("SAL_SaleOrder", "FBILLNO", filter, BillNumber.class);
        List<Order> orders = new ArrayList<>();
        if (!ObjectUtils.isEmpty(orderNumbers)) {
            orderNumbers.forEach(billNumber -> {
                String bill = billNumber.getFBILLNO();
                Map<String, Object> content = Map.of("Number", bill);
                // 查询订单详情
                String response = k3CloudApiService.view("SAL_SaleOrder", content, new BasicResponseHandler());
                if (log.isDebugEnabled()) {
                    log.debug(response);
                }
                boolean processSuccess = true;
                Map responseMap = null;
                try {
                    responseMap = objectMapper.readValue(response, Map.class);
                } catch (JsonProcessingException e) {
                    processSuccess = false;
                    log.error("类型转换失败。{} -> {}", Map.class.getName(), Order.class.getName(), e);
                }
                // 将订单详情封装成响应数据
                if (processSuccess && Objects.nonNull(responseMap)) {
                    Map responseStatus = (Map) ((Map) responseMap.get("Result")).get("ResponseStatus");
                    if (!(Boolean) responseStatus.get("IsSuccess")) {
                        throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.KINGDEE_006,
                                responseStatus.get("Errors"));
                    }
                    Map dataMap = (Map) ((Map) responseMap.get("Result")).get("Result");
                    try {
                        String dataJson = objectMapper.writeValueAsString(dataMap);
                        Order order = objectMapper.readValue(dataJson, Order.class);
                        orders.add(order);
                    } catch (JsonProcessingException e) {
                        log.error("处理json数据失败。", e);
                    }
                }

            });
        }
        return orders;
    }
    
    public PageResponse<JSONObject> checkOverDeposit(OrderPlanRequest request) {
    	 String username = SecurityContextHolder.getContext().getAuthentication().getName();
         // 查询当前用户信息（销售组织、客户编码、业务员）
         TblCustomerExample example = new TblCustomerExample();
         example.createCriteria().andPhoneNumberEqualTo(username).andDeletedEqualTo(false);
         TblCustomer customer = customerMapper.selectByExample(example).stream().findAny()
                 .orElseThrow(() -> {
                     log.error("当前客户不存在。用户名：[{}]", username);
                     throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.CUS003, username);
                 });
    	 boolean flag = true;
    	 JSONObject jo = new JSONObject();
         if (customer.getNoDepositOrder() != null && customer.getNoDepositOrder().equals("2")) {
        	 double currentDeposit = customer.getDepositAmount();
        	 double orverDeposit = customer.getOverDepositOrder() == null ? 0 : customer.getOverDepositOrder();
        	 double finalDepositAmount = currentDeposit - request.getCheckOrderAmount();
        	 if (finalDepositAmount < 0 && Math.abs(finalDepositAmount) > orverDeposit) {
        		 flag = false;
        	 }
        	 jo.put("orderAmt", request.getCheckOrderAmount());
             jo.put("depositAmt", currentDeposit);
             jo.put("overdepositAmt", orverDeposit);
         }
         jo.put("flag", flag);
         List<JSONObject> countList = new ArrayList<JSONObject>();
         countList.add(jo);
         return PageResponse.<JSONObject>builder()
                 .records(countList)
                 .build();
    }
    
    
    public PageResponse<Integer> checkTodayOrders(OrderPlanRequest request) {
    	int todayCounts = 0;
    	 String username = SecurityContextHolder.getContext().getAuthentication().getName();
         // 查询当前用户信息（销售组织、客户编码、业务员）
         TblCustomerExample example = new TblCustomerExample();
         example.createCriteria().andPhoneNumberEqualTo(username).andDeletedEqualTo(false);
         TblCustomer customer = customerMapper.selectByExample(example).stream().findAny()
                 .orElseThrow(() -> {
                     log.error("当前客户不存在。用户名：[{}]", username);
                     throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.CUS003, username);
                 });
    	
         TblOrderExample orderExample = new TblOrderExample();
         TblOrderExample.Criteria criteria = orderExample.createCriteria();
         criteria.andCustomerIdEqualTo(customer.getId());
         
         LocalDateTime start = LocalDate.now().atStartOfDay();
         
         criteria.andCreateTimeGreaterThanOrEqualTo(start);
             
         criteria.andCreateTimeLessThan(start.plusDays(1));
         
         List<TblOrder> list =  orderMapper.selectByExample(orderExample);
         
         todayCounts = list.size();
         List<Integer> countList = new ArrayList<Integer>();
         countList.add(todayCounts);
         return PageResponse.<Integer>builder()
                 .records(countList)
                 .build();
    }
    
    @Override
    @Transactional
    public void createOrder(OrderPlanRequest request) {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        // 查询当前用户信息（销售组织、客户编码、业务员）
        TblCustomerExample example = new TblCustomerExample();
        example.createCriteria().andPhoneNumberEqualTo(username).andDeletedEqualTo(false);
        TblCustomer customer = customerMapper.selectByExample(example).stream().findAny()
                .orElseThrow(() -> {
                    log.error("当前客户不存在。用户名：[{}]", username);
                    throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.CUS003, username);
                });

        LocalDateTime now = LocalDateTime.now();
        LocalDateTime rule = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 15, 30);
        LocalDateTime ruleEnd = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 17, 0);


        ConfigEntity configEntity = this.configService.getConfig(ApplicationConstant.CONFIG_KEY_RECEIVE_ORDER);
        boolean receiveOrder = true;
        if (configEntity != null) {
            if (configEntity.getConfigValue().equals("0")) {
                receiveOrder = false;
            }
        }
        //今日时间超过3点以后就不能增加订单
        if (!receiveOrder) {
            throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.ORDER_INVALID);
        }

        List<OrderPlanRequest.ProductInfo> products = request.getProductInfos();
        TblOrder order = new TblOrder();

        order.setOrderNo(idGeneratorService.generateId("mh:order:no"));//订单编号
        Double amount = products.stream().mapToDouble(OrderPlanRequest.ProductInfo::getPrice).sum();
        order.setAmount(amount);//物料合计
        Integer qty = products.stream().mapToInt(OrderPlanRequest.ProductInfo::getFqty).sum();
        order.setGoodsNumber(qty);//物料数量
        order.setCustomerId(customer.getId());//客户ID
        order.setWuliuCode(customer.getWuliuCode());//物流线路
        order.setWuliuName(customer.getWuliuName());//物流线路
        order.setFnote(request.getFnote());// 订单备注
        order.setStatus(0); // 未审核

        // 新增订单
        orderMapper.insertSelective(order);
        products.forEach(productInfo -> {
            TblOrderDetails details = new TblOrderDetails();

            details.setOrderId(order.getId());
            details.setMaterialName(productInfo.getMaterialName());
            details.setMaterialCode(productInfo.getProductCode());
            details.setSpecCode(productInfo.getSpecCode());
            details.setSpecName(productInfo.getSpecName());
            details.setNum(productInfo.getFqty());
            details.setPrice(productInfo.getPrice());
            details.setDeliveryDate(productInfo.getFDeliveryDate()
                    .toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
            details.setStatus(0);
            details.setTaocanDetail(productInfo.getTaocanDetail());
            // 新增订单明细
            orderDetailsMapper.insertSelective(details);
        });
        
        // 自动审核
//        auditOrder(order.getId());
        
        // 更新客户预付款和锁定金额并增加预付款明细
        if (customer.getNoDepositOrder() != null && customer.getNoDepositOrder().equals("2")) {
        	// 更新客户预付款和锁定金额
        	customer.setDepositAmount(customer.getDepositAmount() - amount);
        	customer.setLockAmount(customer.getLockAmount() + amount);
        	customerMapper.updateByPrimaryKey(customer);
        	
        	// 增加预付款明细
        	TblDepositDetails deposit = new TblDepositDetails();
        	deposit.setCustomerId(customer.getId());
        	deposit.setDataFrom("客户订单API");
        	deposit.setAmount(customer.getDepositAmount());
        	deposit.setLockAmount(customer.getLockAmount());
        	deposit.setChangeType("订单创建");
        	deposit.setDiffAmount(amount);
        	deposit.setOrderNo(order.getOrderNo());
        	
        	depositDetailsMapper.insert(deposit);
        }
        
        //检查并获取opienid
        TblUserOpenidExample tblUserOpenidExample = new TblUserOpenidExample();
        tblUserOpenidExample.createCriteria().andUserIdEqualTo(customer.getId());
        List<TblUserOpenid> tblUserOpenidList = tblUserOpenidMapper.selectByExample(tblUserOpenidExample);
        Set<String> seenIds = new HashSet<>();
		for (TblUserOpenid openid : tblUserOpenidList) {
			seenIds.add(openid.getOpenId());
		}
		seenIds.forEach(openid -> {
			//服务号发送消息
			wxService.sendMsg(openid, order.getOrderNo(), customer.getName(), "已下单");
		});
    }

    @Override
    public void auditOrder(Long orderId) {

        TblOrder order = orderMapper.selectByPrimaryKey(orderId);
        log.debug(String.format("传单id%s",orderId));
        System.out.println(String.format("传单id%s",orderId));
        if (Objects.isNull(order)) {
            log.error("该订单[{}]不存在。", orderId);
            throw new ErpBusinessException(HttpStatus.NOT_FOUND, ApplicationConstant.DATA_NOT_FOUND, "订单", orderId);
        }else{
            String filter = String.format( "F_DLMH_CRMID = '%s' ", order.getOrderNo());
            List<BillNumber> orderNumbers = k3CloudApiService
                    .executeBillQuery("SAL_SaleOrder", "FBILLNO", filter, BillNumber.class);
            if (orderNumbers.size()>0){
                return;
            }
        }
        // 客户信息查询
        TblCustomer customer = customerMapper.selectByPrimaryKey(order.getCustomerId());
        if (Objects.isNull(customer)) {
            log.error("该客户[{}]不存在。", order.getCustomerId());
            throw new ErpBusinessException(HttpStatus.NOT_FOUND, ApplicationConstant.DATA_NOT_FOUND, "客户信息", order.getCustomerId());
        }

        String cusFnumber = customer.getCustomerNum();


        OrderForm orderForm = new OrderForm();
        orderForm.setDeleteEntry(true);
        orderForm.setVerifyBaseDataField(false);
        orderForm.setEntryBatchFill(true);
        orderForm.setValidateFlag(true);
        orderForm.setNumberSearch(true);

        OrderForm.Model model = new OrderForm.Model();

        // 单据类型：FBillTypeID  (必填项)
        model.setFBillTypeID(new NumberRecord(ApplicationConstant.STANDARD_ORDER_CODE)); // 标准销售订单Code

        // 销售组织：FSaleOrgId  (必填项)
        model.setFSaleOrgId(new NumberRecord("100"));
//        model.setFSaleDeptId(new NumberRecord(customer.getOrganizationCode()));

        // 客户：FCustId  (必填项)
        model.setFCustId(new NumberRecord(customer.getCustomerNum()));
        model.setFReceiveId(new NumberRecord(customer.getCustomerNum()));

        // 销售员：FSalerId  (必填项)
        model.setFSalerId(new NumberRecord(customer.getBizCode()));

        // 增加订单备注
        model.setFNote(order.getFnote());

        // 增加送货线路
        model.setF_DLMH_Text(order.getWuliuName());
        // 增加送货路线 code 2021/12/20
        model.setF_DLMH_Assistant(new NumberRecord(order.getWuliuCode()));

        //1027mjy
        model.setF_DLMH_CRMID(order.getOrderNo());


        // 财务信息FSaleOrderFinance
        OrderForm.Model.SaleOrderFinance finance = new OrderForm.Model.SaleOrderFinance();

        // 结算币别：FSettleCurrId  (必填项)
        finance.setFSettleCurrId(new NumberRecord("PRE001"));
        finance.setFIsPriceExcludeTax(true);
        finance.setFIsIncludedTax(true);

        if(order.getAmount()!=null&&order.getAmount()!=0){//赠品不添加收款条件
            String fFRecConditionId = this.queryFRECCONDITIONID(cusFnumber);

            if(!"".equals(fFRecConditionId) && fFRecConditionId!=null){
                NumberRecord ffrcid = new NumberRecord(fFRecConditionId);
                finance.setFFRecConditionId(ffrcid);
            }else if(customer.getShoukuanCode()!=null && !"".equals(customer.getShoukuanCode())){
                NumberRecord ffrcid = new NumberRecord(customer.getShoukuanCode());
                finance.setFFRecConditionId(ffrcid);
            }

        }else{
            NumberRecord ffrcid = new NumberRecord("");
            finance.setFFRecConditionId(ffrcid);

        }
        model.setFSaleOrderFinance(finance);

        TblOrderDetailsExample example = new TblOrderDetailsExample();
        example.createCriteria().andOrderIdEqualTo(orderId);
        List<TblOrderDetails> orderDetails = orderDetailsMapper.selectByExample(example);

        // 订单明细：FSaleOrderEntry
        List<OrderForm.Model.SaleOrderEntry> list = new ArrayList<>();
        for (TblOrderDetails details : orderDetails) {

            OrderForm.Model.SaleOrderEntry saleOrderEntry = new OrderForm.Model.SaleOrderEntry();

            if (details.getCategoryCode() != null && details.getCategoryCode().equals(ApplicationConstant.SUIT_CATEGORY_CODE)) {
                //套件父项
                saleOrderEntry.setFROWTYPE("Parent");
            }

            // 结算含税单价
            saleOrderEntry.setFTaxPrice(details.getPrice() / details.getNum());
            //是否赠品
            if(details.getPrice() == 0){
                saleOrderEntry.setFIsFree("true");
            }else{
                saleOrderEntry.setFIsFree("false");
            }
            // 物料编码  (必填项)
            saleOrderEntry.setFMaterialId(new NumberRecord(details.getMaterialCode()));

            // 销售单位  (必填项)
            saleOrderEntry.setFUnitID(new NumberRecord(ApplicationConstant.DEFAULT_UNIT_ID));

            // 要货日期获取
            F_DLMH_DATE = details.getDeliveryDate();

            //客户编码 ERP方要求
            saleOrderEntry.setF_DLMH_Base(new NumberRecord(customer.getCustomerNum()));

            if ("715001".equals(details.getMaterialCode()) || "715002".equals(details.getMaterialCode())) {
                // 配料的辣椒油, 榨菜不传金蝶
                continue;
            }
            Double specNum = 0.0;
            switch (details.getMaterialCode()) {
                case "715001":
                    //辣椒油
                    specNum = Double.parseDouble(String.valueOf(details.getNum() * 3.0 / 500));
                    break;
                case "715002":
                    //榨菜
                    specNum = Double.parseDouble(String.valueOf(details.getNum() * 9.0 / 500));
                    break;
                case "715003":
                    //香葱
                    specNum = Double.parseDouble(String.valueOf(details.getNum() * 4.5 / 500));
                    break;
                default:
                    //其他
                    specNum = Double.parseDouble(String.valueOf(details.getNum()));
            }

            // 设置物料数量
            saleOrderEntry.setFQty(specNum);

            // 计价单位 (必填项)
            saleOrderEntry.setFPriceUnitId(new NumberRecord(ApplicationConstant.DEFAULT_UNIT_ID));

            // 要货日期 (必填项)
            saleOrderEntry.setFDeliveryDate(Date.from(details.getDeliveryDate().atZone(ZoneId.systemDefault()).toInstant()));

            saleOrderEntry.setF_DLMH_Date1(new Date());
            saleOrderEntry.setF_DLMH_Remarks(details.getSpecCode());//套餐明细

            // 库存组织 锁定妙禾作为库存组织 100
            saleOrderEntry.setFStockOrgId(new NumberRecord("100"));

            // 结算组织 (必填项)
            saleOrderEntry.setFSettleOrgIds(new NumberRecord("100"));

            // 2021-12-01 追加供货组织 否则套餐不能自动展开，当库存组织固定成 妙禾 100后
            saleOrderEntry.setFSupplyOrgId(new NumberRecord("100"));

            // 预留类型 (必填项)
            saleOrderEntry.setFReserveType(ApplicationConstant.DEFAULT_RESERVE_TYPE);
            // 库存单位 (必填项)
            saleOrderEntry.setFStockUnitID(new NumberRecord(ApplicationConstant.DEFAULT_UNIT_ID));

            list.add(saleOrderEntry);
        }

        // 金蝶订单日期 = crm订单日期
        model.setF_DLMH_DATE(Date.from(order.getCreateTime().atZone(ZoneId.systemDefault()).toInstant()));

        // 金蝶要货日期 = crm要货日期
        model.setFDate(F_DLMH_DATE);

        model.setFSaleOrderEntry(list);
        orderForm.setModel(model);

        if (log.isDebugEnabled()) {
            log.debug("===================================================");
            log.debug("=============  即将提交订单到金蝶ERP系统  =============");
            log.debug("===================================================");
        }

        // 放在要检测的代码段前，取开始前的时间戳
        //Long startTime = System.currentTimeMillis();

        String erpOrderNo = k3CloudApiService.saveOrder(orderForm);

        // 放在要检测的代码段后，取结束后的时间戳
        //Long endTime = System.currentTimeMillis();

        // 计算并打印耗时
        /*Long tempTime = (endTime - startTime);
        System.out.println("金蝶保存花费时间："+
                (((tempTime/86400000)>0)?((tempTime/86400000)+"d"):"")+
                ((((tempTime/86400000)>0)||((tempTime%86400000/3600000)>0))?((tempTime%86400000/3600000)+"h"):(""))+
                ((((tempTime/3600000)>0)||((tempTime%3600000/60000)>0))?((tempTime%3600000/60000)+"m"):(""))+
                ((((tempTime/60000)>0)||((tempTime%60000/1000)>0))?((tempTime%60000/1000)+"s"):(""))+
                ((tempTime%1000)+"ms"));*/

        if (log.isDebugEnabled()) {
            log.debug("===================================================");
            log.debug("==================  订单提交成功！  ==================");
            log.debug("===================================================");
        }
        TblOrder auditedOrder = new TblOrder();
        auditedOrder.setId(order.getId());
        auditedOrder.setErpOrderNo(erpOrderNo);
        auditedOrder.setStatus(1);
        auditedOrder.setOrderStatus("已下单");
        orderMapper.updateByPrimaryKeySelective(auditedOrder);
        
        //检查并获取opienid
		TblUserOpenidExample tblUserOpenidExample = new TblUserOpenidExample();
		tblUserOpenidExample.createCriteria().andUserIdEqualTo(customer.getId());
		List<TblUserOpenid> tblUserOpenidList = tblUserOpenidMapper.selectByExample(tblUserOpenidExample);
		Set<String> seenIds = new HashSet<>();
		for (TblUserOpenid openid : tblUserOpenidList) {
			seenIds.add(openid.getOpenId());
		}
		seenIds.forEach(openid -> {
			//服务号发送消息
		wxService.sendMsg(openid, order.getOrderNo(), customer.getName(), "已审核");
		});
    }

    @Override
    public void auditOrders(List<Long> orderIds) {
        log.debug(orderIds.toString());
        orderIds.forEach(this::auditOrder);
    }

    //客户删除订单
    @Override
    public void deleteOrder(Long orderId) {
        TblOrder order = orderMapper.selectByPrimaryKey(orderId);
        if (Objects.isNull(order)) {
            log.error("该订单[{}]不存在。", orderId);
            throw new ErpBusinessException(HttpStatus.NOT_FOUND, ApplicationConstant.DATA_NOT_FOUND, "订单", orderId);
        }
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime rule = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 15, 30);
        LocalDateTime ruleEnd = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 18, 0);

        ConfigEntity configEntity = this.configService.getConfig(ApplicationConstant.CONFIG_KEY_RECEIVE_ORDER);
        boolean receiveOrder = true;
        if (configEntity != null) {
            if (configEntity.getConfigValue().equals("0")) {
                receiveOrder = false;
            }
        }
        //今日时间超过3点以后就不能删除订单
        if (!receiveOrder) {
            throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.ORDER_DELETE_INVALID);
        }
        orderMapper.deleteByPrimaryKey(orderId);

        //删除订单明细
        TblOrderDetailsExample example = new TblOrderDetailsExample();
        example.createCriteria().andOrderIdEqualTo(orderId);
        orderDetailsMapper.deleteByExample(example);
        
    }

    @Override
    public void adminUpdateOrderExportStatus(OrderExportStatusRequest request) {
        TblOrder tblOrder = new TblOrder();
        tblOrder.setId(request.getId());
        tblOrder.setVersion(request.getStatus() != null && request.getStatus() ? 1L : 0);
        orderMapper.updateByPrimaryKeySelective(tblOrder);
    }

    //管理员删除订单
    @Override
    public void adminDeleteOrder(Long orderId) {
    	// 获取订单信息
    	TblOrder order = orderMapper.selectByPrimaryKey(orderId);
    	
    	orderMapper.deleteByPrimaryKey(orderId);
        //删除订单明细
        TblOrderDetailsExample example = new TblOrderDetailsExample();
        example.createCriteria().andOrderIdEqualTo(orderId);
        orderDetailsMapper.deleteByExample(example);
        
        
        // 客户信息查询
        TblCustomer customer = customerMapper.selectByPrimaryKey(order.getCustomerId());
        
        // 更新客户预付款和锁定金额并增加预付款明细
        if (customer.getNoDepositOrder() != null && customer.getNoDepositOrder().equals("2")) {
        	// 更新客户预付款和锁定金额
        	customer.setDepositAmount(customer.getDepositAmount() + order.getAmount());
        	customer.setLockAmount(customer.getLockAmount() - order.getAmount());
        	customerMapper.updateByPrimaryKey(customer);
        	
        	// 增加预付款明细
        	TblDepositDetails deposit = new TblDepositDetails();
        	deposit.setCustomerId(customer.getId());
        	deposit.setDataFrom("客户订单API");
        	deposit.setAmount(customer.getDepositAmount());
        	deposit.setLockAmount(customer.getLockAmount());
        	deposit.setChangeType("订单删除");
        	deposit.setDiffAmount(order.getAmount());
        	deposit.setOrderNo(order.getOrderNo());
        	
        	depositDetailsMapper.insert(deposit);
        }
        
        //检查并获取OPENID
		TblUserOpenidExample tblUserOpenidExample = new TblUserOpenidExample();
		tblUserOpenidExample.createCriteria().andUserIdEqualTo(customer.getId());
		List<TblUserOpenid> tblUserOpenidList = tblUserOpenidMapper.selectByExample(tblUserOpenidExample);
		Set<String> seenIds = new HashSet<>();
		for (TblUserOpenid openid : tblUserOpenidList) {
			seenIds.add(openid.getOpenId());
		}
		seenIds.forEach(openid -> {
			//服务号发送消息
			wxService.sendMsg(openid, order.getOrderNo(), customer.getName(), "已删除");
		});
    }

    @Override
    @Transactional
    public void adminDeleteOrderDetails(OrderDetailsRequest request) {
        //删除订单明细选定的其中一条
        orderDetailsMapper.deleteByPrimaryKey(request.getId());
        try {
            //重新计算订单的调料包
            updateOrderDetailsOptions(request.getOrderId());
        } catch (Exception e) {
        	e.printStackTrace();
            throw new ErpBusinessException(HttpStatus.BAD_REQUEST, e, ApplicationConstant.COMMON_SERVER_ERR);
        }
        //重新计算订单的调料包
    }

    //管理员删除订单明细
    @Override
    @Transactional
    public void adminUpdateOrderDetails(OrderDetailsRequest request) {

        //修改订单明细得数量
        TblOrderDetails orderDetails = orderDetailsMapper.selectByPrimaryKey(request.getId());
        if (Objects.isNull(orderDetails)) {
            throw new ErpBusinessException(HttpStatus.NOT_FOUND, ApplicationConstant.DATA_NOT_FOUND);
        }

        //修改数量
        if (Objects.nonNull(request.getNum())) {
            //修改商品的价格
            orderDetails.setPrice((orderDetails.getPrice() / orderDetails.getNum()) * request.getNum());
            orderDetails.setNum(request.getNum());
        }

        //修改价格
        if (Objects.nonNull(request.getPrice())) {
            orderDetails.setPrice(request.getPrice() * orderDetails.getNum());
        }
        orderDetailsMapper.updateByPrimaryKeySelective(orderDetails);

        try {
            //重新计算订单的调料包
            updateOrderDetailsOptions(request.getOrderId());

        } catch (Exception e) {
            throw new ErpBusinessException(HttpStatus.BAD_REQUEST, e, ApplicationConstant.COMMON_SERVER_ERR);
        }

    }

    private void updateOrderDetailsOptions(Long orderId) throws NoSuchFieldException, IllegalAccessException {

        //删除 lajiaoyou，zhacai，xiangcong,liaobao,xiaohuntun,yunfei
        TblOrderDetailsExample example = new TblOrderDetailsExample();
        TblOrderDetailsExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        criteria.andMaterialCodeIn(List.of("715001", "715002", "715003", "603163", "715013", "yunfei"));
        orderDetailsMapper.deleteByExample(example);

        //查询订单下的明细
        TblOrder order = orderMapper.selectByPrimaryKey(orderId);
        List<OrderDetailPriceStrategyEntity> orderDetails = orderDetailsMapper.selectPriceStrategyByExample(orderId);

        this.addExtraProduct("lajiaoyou", "715001", "辣椒油包", "斤", orderId, orderDetails);
        this.addExtraProduct("zhacai", "715002", "榨菜", "斤", orderId, orderDetails);
        this.addExtraProduct("xiangcong", "715003", "香葱", "斤", orderId, orderDetails);
        this.addExtraProduct("liaobao", "603163", "馄饨料包", "袋", orderId, orderDetails);
        this.addExtraProduct("xiaohuntun", "715013", "小馄饨料粉", "袋", orderId, orderDetails);

        //保存运费
        double sum = 0L;
        var finalAmount = orderDetails.stream().mapToDouble(OrderDetailPriceStrategyEntity::getPrice).sum();
        Long customerId = order.getCustomerId();
        TblCustomer customer = customerMapper.selectByPrimaryKey(customerId);
        var orderQty = customer.getOrderQty() == null ? 0 : customer.getOrderQty();
        int orderFee = customer.getFreightFee() == null ? 0 : customer.getFreightFee();

        //起订量大于0的情况
        if (orderQty > 0) {
            //订单金额合计大于起订金额就免费
            if (finalAmount > orderQty) {
                orderFee = 0;
            }
        }

        if (orderFee > 0) {
            TblOrderDetails tblOrderDetails = new TblOrderDetails();
            tblOrderDetails.setMaterialCode("yunfei");
            tblOrderDetails.setMaterialName("运费");
            tblOrderDetails.setNum(1);
            tblOrderDetails.setPrice((double) orderFee);
            tblOrderDetails.setOrderId(orderId);
//            tblOrderDetails.setDeliveryDate(LocalDateTime.now());
            tblOrderDetails.setDeliveryDate(orderDetails.get(0).getDeliveryDate());
            tblOrderDetails.setStatus(0);
            orderDetailsMapper.insertSelective(tblOrderDetails);
        }


        //更新订单的合计
        TblOrder tblOrder = new TblOrder();
        tblOrder.setId(orderId);
        double amount = finalAmount + orderFee;
        
        // 获取原订单金额获取差异值
        TblOrder oldOrder = orderMapper.selectByPrimaryKey(orderId);
        double differentAmount = oldOrder.getAmount() - amount;
        
        tblOrder.setAmount(amount);
        Integer qty = orderDetails.stream().mapToInt(OrderDetailPriceStrategyEntity::getNum).sum();
        tblOrder.setGoodsNumber(qty);
        orderMapper.updateByPrimaryKeySelective(tblOrder);
        
        // 更新客户预付款和锁定金额并增加预付款明细
        if (customer.getNoDepositOrder() != null && customer.getNoDepositOrder().equals("2")) {
        	// 更新客户预付款和锁定金额
        	customer.setDepositAmount(customer.getDepositAmount() + differentAmount);
        	customer.setLockAmount(customer.getLockAmount() - differentAmount);
        	customerMapper.updateByPrimaryKey(customer);
        	
        	// 增加预付款明细
        	TblDepositDetails deposit = new TblDepositDetails();
        	deposit.setCustomerId(customer.getId());
        	deposit.setDataFrom("客户订单API");
        	deposit.setAmount(customer.getDepositAmount());
        	deposit.setLockAmount(customer.getLockAmount());
        	deposit.setChangeType("订单详细变更");
        	deposit.setDiffAmount(differentAmount);
        	deposit.setOrderNo(order.getOrderNo());
        	
        	depositDetailsMapper.insert(deposit);
        }
        
        //检查并获取OPENID
  		TblUserOpenidExample tblUserOpenidExample = new TblUserOpenidExample();
  		tblUserOpenidExample.createCriteria().andUserIdEqualTo(customer.getId());
  		List<TblUserOpenid> tblUserOpenidList = tblUserOpenidMapper.selectByExample(tblUserOpenidExample);
  		Set<String> seenIds = new HashSet<>();
		for (TblUserOpenid openid : tblUserOpenidList) {
			seenIds.add(openid.getOpenId());
		}
		seenIds.forEach(openid -> {
			//服务号发送消息
			wxService.sendMsg(openid, order.getOrderNo(), customer.getName(), "订单详细变更");
		});
    }

    private void addExtraProduct(String prop,
                                 String prodcutCode,
                                 String prodcutName,
                                 String specName,
                                 Long orderId,
                                 List<OrderDetailPriceStrategyEntity> orderDetails) throws NoSuchFieldException, IllegalAccessException {


        if (orderDetails.size() > 0) {
            Long count = 0L;
            //计算数量
            for (OrderDetailPriceStrategyEntity item : orderDetails) {
                Class c = item.getClass();
                Field field = c.getDeclaredField(prop);
                field.setAccessible(true);
                Object value = field.get(item);
                //属性勾选的情况下，需要计算数量
                if (value != null && value.equals(Boolean.TRUE)) {
                    count += item.getNum() * (prop.equals("liaobao") ? (item.getSpecNum() == null ? 1 : item.getSpecNum()) : 1);
                }
            }
            if (count > 0) {
                TblOrderDetails tblOrderDetails = new TblOrderDetails();
                tblOrderDetails.setMaterialCode(prodcutCode);
                tblOrderDetails.setMaterialName(prodcutName);
                tblOrderDetails.setSpecName(specName);
                tblOrderDetails.setNum(Integer.valueOf(String.valueOf(count)));
                tblOrderDetails.setPrice((double) 0L);
                tblOrderDetails.setOrderId(orderId);
                tblOrderDetails.setDeliveryDate(orderDetails.get(0).getDeliveryDate());
                tblOrderDetails.setStatus(0);
                orderDetailsMapper.insertSelective(tblOrderDetails);
            }
        }
    }

    @Override
    public void updateDeliveryDate(OrderDeliveryDateRequest request) {
        TblOrderDetailsExample example = new TblOrderDetailsExample();
        example.createCriteria().andOrderIdEqualTo(request.getId());
        TblOrderDetails tblOrderDetails = new TblOrderDetails();
        Instant instant = request.getDeliveryDate().toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        tblOrderDetails.setDeliveryDate(localDateTime);
        orderDetailsMapper.updateByExampleSelective(tblOrderDetails, example);
    }

    //修改订单备注
    @Override
    public void updateOrderMemo(OrderMemoRequest request) {
        TblOrderExample example = new TblOrderExample();
        example.createCriteria().andIdEqualTo(request.getId());
        TblOrder tblOrder = new TblOrder();
        String str = request.getFnote();
        tblOrder.setFnote(str);
        orderMapper.updateByExampleSelective(tblOrder, example);
    }

    //修改订单物流信息
    @Override
    public void updateOrderWuliu(OrderWuliuRequest request) {
        TblOrderExample example = new TblOrderExample();
        example.createCriteria().andIdEqualTo(request.getId());
        TblOrder tblOrder = new TblOrder();
        String wuliu_code = request.getWuliuCode();
        String wuliu_name = request.getWuliuName();
        tblOrder.setWuliuCode(wuliu_code);
        tblOrder.setWuliuName(wuliu_name);
        orderMapper.updateByExampleSelective(tblOrder, example);
    }

    @Override
    public PageResponse<OrderEntity> getOrders(OrderQueryRequest request) {
        TblOrderExample example = new TblOrderExample();
        example.setDistinct(true);
        TblOrderExample.Criteria criteria = example.createCriteria();
        if (Objects.nonNull(request.getStart())) {

            Instant instant = request.getStart().toInstant();
            ZoneId zone = ZoneId.systemDefault();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
            criteria.andCreateTimeGreaterThanOrEqualTo(localDateTime);
        }
        if (Objects.nonNull(request.getEnd())) {
            Instant instant = request.getEnd().toInstant();
            ZoneId zone = ZoneId.systemDefault();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
            criteria.andCreateTimeLessThan(localDateTime.plusDays(1));
        }

        LocalDateTime deliveryStart = null;
        LocalDateTime deliveryEnd = null;

        if (Objects.nonNull(request.getDeliveryStart())) {
            Instant instant = request.getDeliveryStart().toInstant();
            ZoneId zone = ZoneId.systemDefault();
            deliveryStart = LocalDateTime.ofInstant(instant, zone);
        }

        if (Objects.nonNull(request.getDeliveryEnd())) {
            Instant instant = request.getDeliveryEnd().toInstant();
            ZoneId zone = ZoneId.systemDefault();
            deliveryEnd = LocalDateTime.ofInstant(instant, zone).plusDays(1).minusSeconds(1);
        }

        if (Objects.nonNull(deliveryStart) && Objects.nonNull(deliveryEnd)) {
            criteria.andDeliveryDateBetween(deliveryStart, deliveryEnd);
        }

        if (Objects.nonNull(request.getStatus())) {
            criteria.andStatusEqualTo(request.getStatus());
        }

        if (Strings.isNotBlank(request.getCustomerName())) {
            criteria.andCustomerNameLike(StringUtils.quoteWith(request.getCustomerName(), "%"));
        }

        if (Strings.isNotBlank(request.getBizName())) {
            criteria.andBizNameLike(StringUtils.quoteWith(request.getBizName(), "%"));
        }
        //物流线路
        if (request.getWuliuCode()!=null) {
            criteria.andWuliuCodeEqualTo(request.getWuliuCode());
        }
        //金蝶单号
        if (Strings.isNotBlank(request.getErpOrderNo())) {
            criteria.andErpOrderNoLike(StringUtils.quoteWith(request.getErpOrderNo(), "%"));
        }

        if(request.getOrderId()!=null){
            criteria.andIdEqualTo(request.getOrderId());
        }

        if(Strings.isNotBlank(request.getOrganizationCode())){
            criteria.andOrganizationCodeEqualTo(request.getOrganizationCode());
        }

        if(Strings.isNotBlank(request.getCustomerTypeCode())){
            criteria.andCustomerTypeCodeEqualTo(request.getCustomerTypeCode());
        }

        List<String> kindTypeList = new ArrayList<>();
        if (request.getOrganizationCondition() != null) {
            if (request.getOrganizationCondition().contains("加盟店")) {
                kindTypeList.add("2");
            }

            if (request.getOrganizationCondition().contains("渠道店")) {
                kindTypeList.add("1");
            }
        }
        if (kindTypeList.size() > 0) {
            criteria.andCustomerKindCodeIn(kindTypeList);
        }

        if(Strings.isNotBlank(request.getCustomerTypeChildCode())){
            criteria.andCustomerTypeChildCodeEqualTo(request.getCustomerTypeChildCode());
        }

        PageInfo<OrderEntity> pageInfo = PageHelper.startPage(request.getPageNo(), request.getPageSize())
                .doSelectPageInfo(() ->
                        orderApiMapper.selectByExample(example));
        return PageResponse.<OrderEntity>builder()
                .records(pageInfo.getList())
                .totalElement(pageInfo.getTotal())
                .totalPage(pageInfo.getPages())
                .currentPage(pageInfo.getPageNum())
                .build();
    }

    @Override
    public OrderFreightFeeEntity calcFreightFee(OrderFreightFeeRequest request) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        TblCustomerExample customerExample = new TblCustomerExample();
        customerExample.createCriteria().andPhoneNumberEqualTo(authentication.getName()).andDeletedEqualTo(false);
        TblCustomer customer = customerMapper.selectByExample(customerExample)
                .stream().findAny()
                .orElseThrow(() -> {
                    log.error("当前客户不存在。用户名：[{}]", authentication.getName());
                    throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.CUS003, authentication.getName());
                });

        Integer orderQty = customer.getOrderQty();
        Integer freightFee = customer.getFreightFee();
        OrderFreightFeeEntity returnVal = new OrderFreightFeeEntity();
        if (orderQty != null && orderQty > 0) {
            if (request.getAmount() > orderQty) {
                freightFee = 0;
            }
        }
        if (freightFee > 0) {
            // 每天只有第一单算运费
            TblOrderExample orderExample = new TblOrderExample();
            orderExample.setDistinct(true);
            TblOrderExample.Criteria criteria = orderExample.createCriteria();
            criteria.andCustomerIdEqualTo(customer.getId());
            Calendar nowCal = Calendar.getInstance();
            LocalDateTime today = LocalDateTime.of(nowCal.get(Calendar.YEAR), nowCal.get(Calendar.MONTH) + 1, nowCal.get(Calendar.DAY_OF_MONTH), 0, 0);
            criteria.andCreateTimeGreaterThanOrEqualTo(today);
            List<OrderEntity> orderList = orderApiMapper.selectByExample(orderExample);
            if (orderList != null && orderList.size() > 0) {
                freightFee = 0;
            }
        }
        returnVal.setFreightFee(freightFee);
        return returnVal;
    }

    @Override
    public PageResponse<OrderEntity> getCustomerOrders(OrderStatusRequest request) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        TblCustomerExample customerExample = new TblCustomerExample();
        customerExample.createCriteria().andPhoneNumberEqualTo(authentication.getName()).andDeletedEqualTo(false);
        TblCustomer customer = customerMapper.selectByExample(customerExample)
                .stream().findAny()
                .orElseThrow(() -> {
                    log.error("当前客户不存在。用户名：[{}]", authentication.getName());
                    throw new ErpBusinessException(HttpStatus.BAD_REQUEST, ApplicationConstant.CUS003, authentication.getName());
                });
        TblOrderExample orderExample = new TblOrderExample();
        orderExample.setDistinct(true);
        TblOrderExample.Criteria criteria = orderExample.createCriteria();
        criteria.andCustomerIdEqualTo(customer.getId());
        if (request.getStatus() != null) {
            criteria.andStatusEqualTo(request.getStatus());
        }

        PageInfo<OrderEntity> pageInfo = PageHelper.startPage(request.getPageNo(), request.getPageSize())
                .doSelectPageInfo(() -> orderApiMapper.selectByExample(orderExample));
        return PageResponse.<OrderEntity>builder()
                .currentPage(pageInfo.getPageNum())
                .records(pageInfo.getList())
                .totalElement(pageInfo.getTotal())
                .totalPage(pageInfo.getPages())
                .build();
    }


    @Override
    public void exportCustomerOrders(OrderExportRequest request, HttpServletResponse response) {
        TblOrderExample example = new TblOrderExample();
        TblOrderExample.Criteria criteria = example.createCriteria();
        if (request.getIds() != null) {
            Long[] ids = (Long[]) ConvertUtils.convert(request.getIds().split(","), Long.class);
            criteria.andIdIn(Arrays.asList(ids));
        }
        List<OrderEntity> orderEntities = orderApiMapper.selectByExample(example);
        String exportTempName = "template.xlsx";
        String exportFileName = "销售订单列表导出.xlsx";

        try {
            //加载模板
            InputStream exIs = this.getClass().getResourceAsStream("/" + exportTempName);
            //设置jxls相关信息
            Context context = PoiTransformer.createInitialContext();
            context.putVar("title", "销售订单");
            context.putVar("orders", orderEntities);
            //sheet名称
            List<String> orderNos = orderEntities.stream().map(OrderEntity::getOrderNo).collect(Collectors.toList());
            context.putVar("sheetNames", orderNos);

            //生成导出文件
            File tempFile = new File(System.getProperty("java.io.tmpdir") + File.separator + System.currentTimeMillis());
            OutputStream os = new BufferedOutputStream(new FileOutputStream(tempFile));
            JxlsHelper.getInstance().processTemplate(exIs, os, context);

            //导出下载
            InputStream is = new BufferedInputStream(new FileInputStream(tempFile));
            byte[] buffer = new byte[1024];
//            is.read(buffer);
//            is.close();
            response.reset();
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(exportFileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            response.addHeader("Content-Length", "" + tempFile.length());
            OutputStream toClient = response.getOutputStream();
            response.setContentType("application/octet-stream");
            int i = is.read(buffer);
            while (i != -1) {
                toClient.write(buffer, 0, i);
                i = is.read(buffer);
            }
            is.close();
            //toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    @Override
    public void exportERPOrders(OrderCustomRequest request, HttpServletResponse response) {

        TblOrderErpExample example = new TblOrderErpExample();
        //开始时间
        LocalDateTime start = null;
        LocalDateTime end = null;
        if (request.getStart() != null) {

            start = request.getStart().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            example.setDeliveryStartDate(start.minusSeconds(1));
        }
        if (request.getEnd() != null) {
            end = request.getEnd().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            example.setDeliveryEndDate(end.plusDays(1).minusSeconds(1));
        }

        //物流线
        if (request.getWuliuCode() != null && request.getWuliuCode().size() > 0) {
            example.setWuliuCode(request.getWuliuCode());
        }

        List<String> kindTypeList = new ArrayList<>();
        if (request.getCondition() != null) {
            if (request.getCondition().contains("Franchise")) {
                // 加盟店
                kindTypeList.add("2");
            }

            if (request.getCondition().contains("Channel")) {
                // 渠道店
                kindTypeList.add("1");
            }
        }
        if (kindTypeList.size() > 0) {
            example.setCustomerKindCode(kindTypeList);
        }

//        List<String> customerTypeChildCode = new ArrayList<>();
//        //加盟店 301是加盟
//        if (request.getCondition().contains("Franchise")) {
//            customerTypeChildCode.addAll(List.of("301"));
//        }
//
//        //渠道店 202-205是渠道
//        if (request.getCondition().contains("Channel")) {
//            customerTypeChildCode.addAll(List.of("202", "203", "204", "205", "208"));
//        }
//        if (customerTypeChildCode.size() > 0) {
//            example.setCustomerTypeChildCode(customerTypeChildCode);
//        }

        //客户ID
        if (request.getCustomerId() != null && request.getCustomerId() > 0) {
            example.setCustomerId(request.getCustomerId());
        }

        if (request.getAllExport() != null && !request.getAllExport()) {
            example.setAllExport(request.getAllExport());
        }

        if (request.getExportType().equals(REPORT_EXPORT_TYPE_PACKAGE)) {
//            example.setCategoryCode(ApplicationConstant.PACKAGE_CATEGORY_CODE);
            exportPackageReport(example, response, ApplicationConstant.PACKAGE_CATEGORY_CODE, ApplicationConstant.SUIT_CATEGORY_CODE);
        } else {
            exportDriverReport(orderMapper.selectByErpExample(example), start, end, response);
        }
    }

    @Override
    public void modOutQty(OrderDetailsModQtyRequest request, HttpServletResponse response,String direction) {


        if(request.getModInfos() != null && request.getModInfos().size()>0){

            String orderId = request.getFnumber();
            TblOrderExample ordexample = new TblOrderExample();
            ordexample.createCriteria().andErpOrderNoEqualTo(orderId);
            List< TblOrder  > ordList = orderMapper.selectByExample(ordexample);

            if(ordList.size() > 0){
                Long oid = ordList.get(0).getId();
                List<OrderDetailsModQtyRequest.ModOrderInfo> modOrderInfoList = request.getModInfos();
                for(OrderDetailsModQtyRequest.ModOrderInfo info :modOrderInfoList){
                    String productCode = info.getProductCode();
                    double qty = info.getFqty();

                    TblOrderDetails record = new TblOrderDetails();
                    TblOrderDetailsExample example = new TblOrderDetailsExample();
                    TblOrderDetailsExample. Criteria criteria =  example.createCriteria();
                    criteria.andMaterialCodeEqualTo(productCode);
                    criteria.andOrderIdEqualTo(oid);

                    List <TblOrderDetails> detailList = orderDetailsMapper.selectByExample(example);
                    if(detailList.size()>0){
                        TblOrderDetails detail = detailList.get(0);
                        double outqty = detail.getOutstockQty();
                        double specNum = 0;
                        switch (detail.getMaterialCode()) {
                            case "715001":
                                //辣椒油
                                specNum = Double.parseDouble(String.valueOf(qty * 500 / 3.0 ));
                                break;
                            case "715002":
                                //榨菜
                                specNum = Double.parseDouble(String.valueOf(qty * 500 / 9.0));
                                break;
                            case "715003":
                                //香葱
                                specNum = Double.parseDouble(String.valueOf(qty * 500 / 4.5 ));
                                break;
                            default:
                                //其他
                                specNum = Double.parseDouble(String.valueOf(qty));
                        }
                        if("add".equals(direction)){
                            detail.setOutstockQty(outqty+specNum);
                        }else if("sub".equals(direction)){
                            detail.setOutstockQty(outqty-specNum);
                        }
                        detail.setUpdateTime(LocalDateTime.now());
                        orderDetailsMapper.updateByExampleSelective(detail, example);
                    }
                }
            }
        }
  }



    //集装箱导出报表
    private void exportPackageReport(TblOrderErpExample example, HttpServletResponse response, String... categorys) {

        List<OrderErpEntity> orderErpEntities = orderMapper.selectByErpExampleCategory(example, Arrays.asList(categorys));
        List<OrderErpEntity> realList = new ArrayList<>();
        for(OrderErpEntity entity: orderErpEntities) {
            String categoryCode = entity.getCategoryCode();
            if (ApplicationConstant.SUIT_CATEGORY_CODE.equals(categoryCode)) {
                String taocanDetail = entity.getTaocanDetail();
                if (!StringUtil.isEmpty(taocanDetail)) {
                    int pGoodsNumber = entity.getGoodsNumber();
                    try {
                        JSONObject obj = JSONObjectUtils.parse("{\"a\":" + taocanDetail + "}");
                        JSONArray array = (JSONArray)obj.get("a");
                        for (Object o : array) {
                            JSONObject detail = (JSONObject) o;
//                            [{"FNUMERATOR":1.0,"F_DLMH_ZXWLFZMC":"馄饨","F_DLMH_ZXWLFZ":"507","FMATERIALIDCHILD":137590,"FBPStoreUnitID":"份","FCHILDITEMNAME":"海鲜全家福馄饨海鲜汤(冻)","FCHILDITEMMODEL":"290g\/10粒"},{"FNUMERATOR":1.0,"F_DLMH_ZXWLFZMC":"小吃","F_DLMH_ZXWLFZ":"515","FMATERIALIDCHILD":140784,"FBPStoreUnitID":"袋","FCHILDITEMNAME":"可口萝卜","FCHILDITEMMODEL":" "},{"FNUMERATOR":1.0,"F_DLMH_ZXWLFZMC":"半成品","F_DLMH_ZXWLFZ":"501","FMATERIALIDCHILD":140787,"FBPStoreUnitID":"袋","FCHILDITEMNAME":"9g馄饨汤料","FCHILDITEMMODEL":"9g*300袋\/箱"}]
                            String subCategoryCode = detail.getAsString("F_DLMH_ZXWLFZ");
                            String subCategoryName = detail.getAsString("F_DLMH_ZXWLFZMC");
                            String subMaterialCode = detail.getAsString("FMATERIALIDCHILD");
                            String subMaterialName = detail.getAsString("FCHILDITEMNAME");
                            int numerator = detail.getAsNumber("FNUMERATOR").intValue();
                            if (!"馄饨".equals(subCategoryName)) {
                                continue;
                            }
                            OrderErpEntity d = new OrderErpEntity();
                            d.setWuliuName(entity.getWuliuName());
                            d.setWuliuOrder(entity.getWuliuOrder());
                            d.setCustomerId(entity.getCustomerId());
                            d.setCustomerName(entity.getCustomerName());
                            d.setCategoryCode(ApplicationConstant.PACKAGE_CATEGORY_CODE);
                            d.setCustomerTypeChildCode(entity.getCustomerTypeChildCode());
                            d.setCategoryName(subCategoryName);
                            d.setMaterialCode(subMaterialCode);
                            d.setMaterialName(subMaterialName);
                            d.setGoodsNumber(pGoodsNumber * numerator);
                            realList.add(d);
                        }
                    } catch (ParseException ignored) {
                    }
                }

            } else {
                realList.add(entity);
            }
        }

        //先按照 路线 + | + 店家 + | + code 分组
        //这样 路线 + 店家 下的馄饨一览就整理出来了
        Map<String, List<OrderErpEntity>> orderGroupMap = realList.stream().collect(Collectors.groupingBy(p -> String.format("%09d", p.getWuliuOrder()) + "|" + p.getCustomerName() + "|" + p.getCustomerTypeChildCode() + "|" + p.getWuliuName()));

        //装箱集合
        List<OrderErpExportEntity> allBoxs = new ArrayList<>();

        List<String> keyList = orderGroupMap.keySet().stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
        //每组开始以24份/箱进行拆分
        for (String key : keyList) {
            List<OrderErpEntity> items = orderGroupMap.get(key);
            List<OrderErpExportEntity> boxItems = InBox(key, items);
            if (boxItems.size() > 0) {
                allBoxs.addAll(boxItems);
            }
        }

//        //更新订单详细的标识
//        if (example.getAllExport() != null && !example.getAllExport()) {
//            List<Long> materialIds = orderErpEntities.stream().map(OrderErpEntity::getMaterialId).collect(Collectors.toList());
//            if (materialIds.size() > 0) {
//                //执行更新操作
//                orderDetailsMapper.updateByMaterialIds(materialIds);
//            }
//        }

        String exportTempName = "packageTemplate.xls";
        String exportFileName = "装箱单导出.xls";

        try {
            //加载模板
            InputStream exIs = this.getClass().getResourceAsStream("/" + exportTempName);
            //设置jxls相关信息
            Context context = PoiTransformer.createInitialContext();
            context.putVar("outBoxs", allBoxs);

            //生成导出文件
            File tempFile = new File(System.getProperty("java.io.tmpdir") + File.separator + System.currentTimeMillis());
            OutputStream os = new BufferedOutputStream(new FileOutputStream(tempFile));
            JxlsHelper.getInstance().processTemplate(exIs, os, context);

            //导出下载
            InputStream is = new BufferedInputStream(new FileInputStream(tempFile));
            byte[] buffer = new byte[2048];
//            is.read(buffer);
//            is.close();
            response.reset();
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(exportFileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            response.addHeader("Content-Length", "" + tempFile.length());
            OutputStream toClient = response.getOutputStream();
            response.setContentType("application/octet-stream");
            int i = is.read(buffer);
            while (i != -1) {
                toClient.write(buffer, 0, i);
                i = is.read(buffer);
            }
            is.close();
            //toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    private List<OrderErpExportEntity> InBox(String boxInfo, List<OrderErpEntity> orderItems) {

        List<OrderErpEntity> tempItems = new ArrayList<>();
        Map<String, OrderErpEntity> kanjiMap = new HashMap<>();
        for(OrderErpEntity oi: orderItems) {
            OrderErpEntity existObj = null;
            for(OrderErpEntity i: tempItems) {
                if (oi.getMaterialCode().equals(i.getMaterialCode())) {
                    existObj = i;
                    break;
                }
            }
            if (existObj != null) {
                existObj.setGoodsNumber(existObj.getGoodsNumber() + oi.getGoodsNumber());
            } else {
                existObj = new OrderErpEntity();
                existObj.setWuliuName(oi.getWuliuName());
                existObj.setCustomerId(oi.getCustomerId());
                existObj.setCustomerName(oi.getCustomerName());
                existObj.setCategoryCode(oi.getCategoryCode());
                existObj.setCustomerTypeChildCode(oi.getCustomerTypeChildCode());
                existObj.setCategoryName(oi.getCategoryName());
                existObj.setMaterialCode(oi.getMaterialCode());
                existObj.setMaterialName(oi.getMaterialName());
                existObj.setGoodsNumber(oi.getGoodsNumber());
                tempItems.add(existObj);
                kanjiMap.put(oi.getMaterialName(), existObj);
            }
        }
        List<String> tempKeys = new ArrayList<>(kanjiMap.keySet());
        tempKeys.sort(kanjiCollator);
        List<OrderErpEntity> items = new ArrayList<>();
        for(String key: tempKeys) {
            items.add(kanjiMap.get(key));
        }
//        items.sort((a, b) -> {
//            String aM = a.getMaterialName() == null? "": a.getMaterialName();
//            String bM = b.getMaterialName() == null? "": b.getMaterialName();
//            return aM.compareTo(bM);
//        });


        //先根据商品总数计算出需要分几个箱子
        int count = items.stream().mapToInt(OrderErpEntity::getGoodsNumber).sum();
        int boxCount = count / pageSize;
        if (count % pageSize != 0) {
            boxCount++;
        }

        List<OrderErpExportEntity> outBoxs = new ArrayList<>();

        //第一步先把箱子的LIST创建好
        for (int i = 1; i <= boxCount; i++) {
            //物流路线，会员姓名 作为主体
            //orderEntities 这个是具体的商品成员， 要以24件进行划分
            var keys = boxInfo.split("\\|");
            OrderErpExportEntity boxEntity = new OrderErpExportEntity();
            boxEntity.setBoxNo("No." + i);
            boxEntity.setWuliuName(keys[3]);
            boxEntity.setCustomerName(keys[1]);
            boxEntity.setBoxSum(count);
            boxEntity.setCustomerTypeChildCode(keys[2]);
            boxEntity.setOrderDetailEntities(new ArrayList<>());
            outBoxs.add(boxEntity);
        }

        int place = 0;
        int sum1 = 0;
        int num = 0;
        //第二步遍历商品，然后根据商品数量进行装箱分配。
        for (int y = 0; y < boxCount; y++) {
            //System.out.println(outBoxs.get(y).getWuliuName());//线路名称
            //System.out.println(outBoxs.get(y).getCustomerName());//客户名称
            //System.out.println("No." + (y + 1));//箱号
            for (int i = place; i < items.size(); i++) {
                num = items.get(i).getGoodsNumber();
                sum1 = sum1 + num;
                if (num != 0 && sum1 <= pageSize) {
//                    System.out.print(items.get(i).getMaterialName() + ": ");
//                    System.out.println(num);
                    outBoxs.get(y).getOrderDetailEntities().add(items.get(i));
                } else {
                    if (num == 0) {
                        break;
                    }
                    place = i;//在这个位置拆分数量
                    if (24 - (sum1 - num) != 0) {
                        //System.out.print(items.get(i).getMaterialName() + ": ");
                        //System.out.print(pageSize - (sum1 - num));
                        //System.out.println();

                        //生成新对象插入到箱子里
                        OrderErpEntity newItem = new OrderErpEntity();
                        newItem.setGoodsNumber(pageSize - (sum1 - num));
                        newItem.setCustomerName(items.get(i).getCustomerName());
                        newItem.setCustomerId(items.get(i).getCustomerId());
                        newItem.setMaterialName(items.get(i).getMaterialName());
                        newItem.setMaterialCode(items.get(i).getMaterialCode());
                        newItem.setCustomerTypeChildCode(items.get(i).getCustomerTypeChildCode());
                        newItem.setWuliuName(items.get(i).getWuliuName());
                        outBoxs.get(y).getOrderDetailEntities().add(newItem);
                    }
                    //将这个位置的数量更新掉
                    items.get(i).setGoodsNumber(items.get(i).getGoodsNumber() - (pageSize - (sum1 - num)));
                    break;
                }
            }
            //System.out.println("==================");
            sum1 = 0;
        }
        return outBoxs;
    }


    //司机专用单报表
    private void exportDriverReport(List<OrderErpEntity> orderErpEntities, LocalDateTime start, LocalDateTime end, HttpServletResponse response) {
        List<OrderErpEntity> realList = new ArrayList<>();
        for(OrderErpEntity entity: orderErpEntities) {
            String taocanDetail = entity.getTaocanDetail();
            if (!StringUtil.isEmpty(taocanDetail)) {
                int pGoodsNumber = entity.getGoodsNumber();
                try {
                    JSONObject obj = JSONObjectUtils.parse("{\"a\":" + taocanDetail + "}");
                    JSONArray array = (JSONArray)obj.get("a");
                    for (Object o : array) {
                        JSONObject detail = (JSONObject) o;
                        String categoryCode = detail.getAsString("F_DLMH_ZXWLFZ");
                        String categoryName = detail.getAsString("F_DLMH_ZXWLFZMC");
                        String materialCode = detail.getAsString("FMATERIALIDCHILD");
                        int numerator = detail.getAsNumber("FNUMERATOR").intValue();
                        OrderErpEntity d = new OrderErpEntity();
                        d.setWuliuName(entity.getWuliuName());
                        d.setCustomerId(entity.getCustomerId());
                        d.setCustomerName(entity.getCustomerName());
                        d.setCategoryCode(categoryCode);
                        d.setCategoryName(categoryName);
                        d.setMaterialCode(materialCode);
                        d.setGoodsNumber(pGoodsNumber * numerator);
                        realList.add(d);
                    }
                } catch (ParseException e) {
                    realList.add(entity);
                }
            } else {
                realList.add(entity);
            }
        }

        //获取所有的路线
        Map<String, List<OrderErpEntity>> wuliuMaps = realList.stream().collect(Collectors.groupingBy(OrderErpEntity::getWuliuName));

        //获取到所有的品名
        var materialSet = realList.stream().collect(Collectors.groupingBy(p -> StringUtil.isEmpty(p.getCategoryName())? p.getCategoryCode(): p.getCategoryName())).keySet();

        //获取到所有的品名
        List<OrderDetailEntity> materialList = new ArrayList<>();
        for (String key : materialSet) {
            OrderDetailEntity item = new OrderDetailEntity();
//            var keys = key.split("\\|");
//            item.setMaterialCode(keys[0]);
//            item.setMaterialName(keys[1]);
            item.setMaterialName(key);
            materialList.add(item);
        }

        List<OrderDriverExportEntity> driverExportEntities = new ArrayList<>();

        //针对每个路线下，每个客户订购的品名数量进行设置，没有的情况下就是空
        for (String wuliuName : wuliuMaps.keySet()) {

            //记录每条路线
            OrderDriverExportEntity entity = new OrderDriverExportEntity();
            entity.setWuliuName(wuliuName);
            entity.setOrderCustomerEntities(new ArrayList<>());
            entity.setOrderMaterialsSumList(new ArrayList<>());


            //查询该路线下所有的商品
            List<OrderErpEntity> orderErpEntityList = wuliuMaps.get(wuliuName);

            //该路线下所有的店铺
            var customerInfoKey = orderErpEntityList.stream().collect(Collectors.groupingBy(p -> p.getCustomerId() + "|" + p.getCustomerName())).keySet();

            //针对每个店铺获取到最大品名的购买数量，如果有就拿到值
            for (String key : customerInfoKey) {

                //拆分会员主键
                OrderCustomerEntity item = new OrderCustomerEntity();
                var keys = key.split("\\|");
                item.setCustomerId(Integer.valueOf(keys[0]));
                item.setCustomerName(keys[1]);
                item.setOrderErpEntities(new ArrayList<>());

                //针对所有的品名，获取客户对应品名的购买数量
                for (OrderDetailEntity allItem : materialList) {

                    OrderErpEntity orderErpEntity = new OrderErpEntity();
                    orderErpEntity.setMaterialCode(allItem.getMaterialCode());
                    orderErpEntity.setMaterialName(allItem.getMaterialName());
                    AtomicReference<Double> total = new AtomicReference<>((double) 0);
                    orderErpEntityList.stream().filter(p -> p.getCustomerId().equals(item.getCustomerId()) && p.getCategoryName().equals(allItem.getMaterialName())).forEach((details) -> {
                        double specNum = 0.0;
                        switch (details.getMaterialCode()) {
                            case "715001":
                                //辣椒油 不体现在装箱单
//                                specNum = Double.parseDouble(String.valueOf(details.getGoodsNumber() * 3.0 / 500));
                                break;
                            case "715002":
                                //榨菜 不体现在装箱单
//                                specNum = Double.parseDouble(String.valueOf(details.getGoodsNumber() * 9.0 / 500));
                                break;
                            case "715003":
                                //香葱
                                specNum = Double.parseDouble(String.valueOf(details.getGoodsNumber() * 4.5 / 500));
                                break;
                            default:
                                //其他
                                specNum = Double.parseDouble(String.valueOf(details.getGoodsNumber()));
                        }
                        total.set(total.get() + specNum);
                    });
                    orderErpEntity.setSpecNum(total.get());
                    item.getOrderErpEntities().add(orderErpEntity);
                }
                //将店铺保存改路线下
                entity.getOrderCustomerEntities().add(item);
            }


            //该物流路线下，各个品名的数量合计
            for (OrderDetailEntity materialItem : materialList) {

                double total = 0;
                for (var customerEntity : entity.getOrderCustomerEntities()) {
                    var result = customerEntity.getOrderErpEntities().stream().filter(p -> p.getMaterialName().equals(materialItem.getMaterialName())).findFirst().orElseGet(() -> null);
                    if (result != null) {
                        total += result.getSpecNum();
                    }
                }

                //保存各个品名合计
                OrderErpEntity erpEntity = new OrderErpEntity();
                erpEntity.setMaterialCode(materialItem.getMaterialCode());
                erpEntity.setMaterialName(materialItem.getMaterialName());
                erpEntity.setSpecNum(total);
                entity.getOrderMaterialsSumList().add(erpEntity);
            }

            //路线保存到司机专属对象中
            driverExportEntities.add(entity);
        }

        //开始设定Excel
        String exportTempName = "driverTemplate.xlsx";
        String exportFileName = "司机专用单导出.xlsx";

        try {
            XlsCommentAreaBuilder.addCommandMapping("each", EachRightCommand.class);
            //加载模板
            InputStream exIs = this.getClass().getResourceAsStream("/" + exportTempName);
            //设置jxls相关信息
            Context context = PoiTransformer.createInitialContext();
            context.putVar("outBoxs", driverExportEntities);
            context.putVar("number", materialList.size());
            context.putVar("materials", materialList);
            context.putVar("startDate", start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            context.putVar("endDate", end.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            context.putVar("wuliuNameSum", driverExportEntities.stream().map(OrderDriverExportEntity::getWuliuName).collect(Collectors.joining(",")));

            //生成导出文件
            File tempFile = new File(System.getProperty("java.io.tmpdir") + File.separator + System.currentTimeMillis());
            OutputStream os = new BufferedOutputStream(new FileOutputStream(tempFile));
            JxlsHelper.getInstance().processTemplate(exIs, os, context);

            //导出下载
            InputStream is = new BufferedInputStream(new FileInputStream(tempFile));
            byte[] buffer = new byte[1024];
//            is.read(buffer);
//            is.close();
            response.reset();
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(exportFileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            response.addHeader("Content-Length", "" + tempFile.length());
            OutputStream toClient = response.getOutputStream();
            response.setContentType("application/octet-stream");
            int i = is.read(buffer);
            while (i != -1) {
                toClient.write(buffer, 0, i);
                i = is.read(buffer);
            }
            is.close();
            //toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

	@Override
	public void updateStatus(String orderNo, String orderStatus) {
		 TblOrderExample tblOrderExample = new TblOrderExample();
		 tblOrderExample.createCriteria().andErpOrderNoEqualTo(orderNo);
		 TblOrder order = orderMapper.selectByExample(tblOrderExample).stream().findAny().get();
		 if(orderStatus.equals("1")) {
			 order.setOrderStatus("发货在途");
		 } else if(orderStatus.equals("2")) {
			 order.setOrderStatus("已完成");
		 }
		 
		 orderMapper.updateByPrimaryKeySelective(order);
		 
		 if (orderStatus.equals("2")) {
			
			 TblCustomer customer = customerMapper.selectByPrimaryKey(order.getCustomerId());
			 if (customer.getNoDepositOrder() != null && customer.getNoDepositOrder().equals("2")) {
	        	// 更新客户预付款和锁定金额
	        	customer.setLockAmount(customer.getLockAmount() - order.getAmount());
	        	customerMapper.updateByPrimaryKey(customer);
	        	
	        	// 增加预付款明细
	        	TblDepositDetails deposit = new TblDepositDetails();
	        	deposit.setCustomerId(customer.getId());
	        	deposit.setDataFrom("客户订单API");
	        	deposit.setAmount(customer.getDepositAmount());
	        	deposit.setLockAmount(customer.getLockAmount());
	        	deposit.setChangeType("订单完成");
	        	deposit.setDiffAmount(order.getAmount());
	        	deposit.setOrderNo(order.getOrderNo());
	        	
	        	depositDetailsMapper.insert(deposit);
	        }
		 }
	}
}
